package finalproject.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultCaret;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

import finalproject.model.rooms.Mapper;

/**
 * Tha gameview classs
 * Represents a simple view composed of a JTextPane, a TextField and a Map button
 * The JTextPane can display coloured text, you can easily use this functionnality thanks to the ColouredDisplayer interface
 * @author Bighetti Nicolas
 *
 */
@SuppressWarnings("serial")
public class GameView extends JPanel implements ColouredDisplayer {

	/**
	 * The normal width of the frame
	 */
	private final static int NORMAL_WIDTH = 500;

	/**
	 * Tha main frame
	 */
	private JFrame frame;
	/**
	 * The panel representing the map
	 */
	private MapPanel mapPanel;
	/**
	 * Allow for user input
	 */
	private JTextField textField;
	/**
	 * Allow for text to be displayed
	 */
	private JTextPane textArea;
	/**
	 * The map button
	 */
	private JButton btnMap = new JButton("Map");

	/**
	 * If the map is displayed or not
	 */
	private boolean mapMaximized = false;

	/**
	 * Build the view
	 * @param mapper the current game mapper
	 */
	public GameView(Mapper mapper)
	{
		super(new BorderLayout(2, 1));

		textField = new JTextField(20);
		textField.setSize(new Dimension(500, 50));

		//We give the textPane a few rules to allow the best display
		//-------------------------------------------------------------
		textArea = new JTextPane();
		textArea.setEditable(false);
		textArea.setSize(new Dimension(500, 450));
		textArea.setFont(new Font("Lucida Console", Font.PLAIN, 13));

		//We set the carret policy to allow the console to keep tracks of the event currently happening by staying at the bottom of the Pane
		//--------------------------------------------------------------------------------------------------------------------------------------
		DefaultCaret d = new DefaultCaret();
		d.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
		textArea.setCaret(d);
		textArea.getCaret().setVisible(false);
		JScrollPane scrollPane = new JScrollPane(textArea);
		scrollPane.getVerticalScrollBar().setAutoscrolls(true);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

		// Configure components
		mapPanel = new MapPanel(mapper);

		Box southBox = Box.createHorizontalBox();
		southBox.add(btnMap);
		southBox.add(textField);

		// Add components to this panel.
		add(mapPanel, BorderLayout.CENTER);
		add(scrollPane, BorderLayout.WEST);
		add(southBox, BorderLayout.SOUTH);

		StringManager.addDisplayer(this);

		// Events
		btnMap.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e)
			{
				toggleMap();
			}
		});
	}

	/**
	 * Toggle the display of the map
	 */
	public void toggleMap()
	{
		if (mapMaximized = !mapMaximized)
			frame.setSize(new Dimension((int) (5. / 2 * NORMAL_WIDTH), 500));
		else
			frame.setSize(new Dimension(NORMAL_WIDTH, 500));
	}

	/**
	 * Display the given string in the given coolor within the JTextPane
	 * @param c the color
	 * @param s the string
	 */
	public void append(Color c, String s)
	{
		StyleContext sc = StyleContext.getDefaultStyleContext();
		AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

		int len = textArea.getDocument().getLength();

		//We need to set the component editable during our modification or else it won't work
		//--------------------------------------------------------------------------------------
		textArea.setEditable(true);
		textArea.setCaretPosition(len);
		textArea.setCharacterAttributes(aset, false);
		textArea.replaceSelection(s);
		
		//Once we are done, we set it uneditable
		//--------------------------------------
		textArea.setEditable(false);
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event dispatch thread.
	 */
	public void displayView()
	{
		// Create and set up the window.
		frame = new JFrame("SSB World of Zuul");
		frame.setSize(new Dimension(NORMAL_WIDTH, 500));
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Add contents to the window.
		frame.add(this);

		// Display the window.
		frame.setVisible(true);
	}

	@Override
	public void displayString(Color c, String output)
	{
		append(c, output);
	}

	/**
	 * Return the TextField and reset it
	 * Allow collection of the inputs
	 * @return the textField content
	 */
	public String getAndRestTextField()
	{
		String tmp = textField.getText();
		textField.setText("");
		return tmp;
	}

	/**
	 * @return the textField
	 */
	public JTextField getTextField()
	{
		return textField;
	}

	/**
	 * @param textField
	 *            the textField to set
	 */
	public void setTextField(JTextField textField)
	{
		this.textField = textField;
	}

	/**
	 * @return the textArea
	 */
	public JTextPane getTextArea()
	{
		return textArea;
	}

	/**
	 * @param textArea
	 *            the textArea to set
	 */
	public void setTextArea(JTextPane textArea)
	{
		this.textArea = textArea;
	}

	/**
	 * Add an action listener to the TextField
	 * @param listener the action listener to add
	 */
	public void addTextFieldActionListener(ActionListener listener)
	{
		textField.addActionListener(listener);
	}
}
